package main

import (
	"errors"
	"io"
	"log"
	"os"
	"sync"
	"time"
	"xiaozhi/config"

	nls "github.com/aliyun/alibabacloud-nls-go-sdk"
)

type TtsUserParam struct {
	F      io.Writer
	Logger *nls.NlsLogger
}

func onTaskFailed(text string, param interface{}) {
	p, ok := param.(*TtsUserParam)
	if !ok {
		log.Default().Fatal("invalid logger")
		return
	}

	p.Logger.Println("TaskFailed:", text)
}

func onSynthesisResult(data []byte, param interface{}) {
	p, ok := param.(*TtsUserParam)
	if !ok {
		log.Default().Fatal("invalid logger")
		return
	}
	_, err := p.F.Write(data)
	if err != nil {
		log.Fatalln("write failed")
		return
	}
}

func onCompleted(text string, param interface{}) {
	p, ok := param.(*TtsUserParam)
	if !ok {
		log.Default().Fatal("invalid logger")
		return
	}

	p.Logger.Println("onCompleted:", text)
}

func onClose(param interface{}) {
	p, ok := param.(*TtsUserParam)
	if !ok {
		log.Default().Fatal("invalid logger")
		return
	}

	p.Logger.Println("onClosed:")
}

func waitReady(ch chan bool, logger *nls.NlsLogger) error {
	select {
	case done := <-ch:
		{
			if !done {
				logger.Println("Wait failed")
				return errors.New("wait failed")
			}
			logger.Println("Wait done")
		}
	case <-time.After(60 * time.Second):
		{
			logger.Println("Wait timeout")
			return errors.New("wait timeout")
		}
	}
	return nil
}

var lk sync.Mutex
var fail = 0
var reqNum = 0

func testMultiInstance(text string) {
	param := nls.SpeechSynthesisStartParam{
		Format:         config.NewTTSConfig().Format,
		SampleRate:     config.NewTTSConfig().SampleRate,
		Voice:          config.NewTTSConfig().Voice,
		Volume:         config.NewTTSConfig().Volume,
		SpeechRate:     config.NewTTSConfig().SpeechRate,
		PitchRate:      config.NewTTSConfig().PitchRate,
		EnableSubtitle: config.NewTTSConfig().EnableSubtitle,
	}
	alyConfig, _ := nls.NewConnectionConfigWithAKInfoDefault(config.NewAsrConfig().ApiUrl, config.NewAsrConfig().AppKey, config.NewAsrConfig().AccessKeyId, config.NewAsrConfig().AccessKeySecret)
	strId := "ID0"
	fname := "demo/test1.wav"
	ttsUserParam := new(TtsUserParam)
	fout, err := os.OpenFile(fname, os.O_RDWR|os.O_TRUNC|os.O_CREATE, 0666)
	logger := nls.NewNlsLogger(os.Stderr, strId, log.LstdFlags|log.Lmicroseconds)
	logger.SetLogSil(false)
	logger.SetDebug(true)
	logger.Printf("Test Normal Case for SpeechRecognition:%s", strId)
	ttsUserParam.F = fout
	ttsUserParam.Logger = logger
	//第三个参数控制是否请求长文本语音合成，false为短文本语音合成
	tts, err := nls.NewSpeechSynthesis(alyConfig, logger, false,
		onTaskFailed, onSynthesisResult, nil,
		onCompleted, onClose, ttsUserParam)
	if err != nil {
		logger.Fatalln(err)
		return
	}

	lk.Lock()
	reqNum++
	lk.Unlock()
	logger.Println("SR start")
	ch, err := tts.Start(text, param, nil)
	if err != nil {
		lk.Lock()
		fail++
		lk.Unlock()
		tts.Shutdown()
	}

	err = waitReady(ch, logger)
	if err != nil {
		lk.Lock()
		fail++
		lk.Unlock()
		tts.Shutdown()
	}
	logger.Println("Synthesis done")
	tts.Shutdown()

}

func main() {
	testMultiInstance("你好小德，今天天气怎么样。")
}
